package com.example.demo.service.impl;

import com.example.demo.dao.CityMapper;
import com.example.demo.domain.City;
import com.example.demo.domain.CityExample;
import com.example.demo.service.CityService;
import com.example.demo.service.DZDPScratchService;
import com.example.demo.thread.CityTask;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Map;
import java.util.Set;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;

/**
 * @author ZhengWei
 * @Description
 * @date 2020/7/16 6:27 下午
 */
@Service
public class CityServiceImpl implements CityService {

    @Autowired
    private DZDPScratchService scratchService;
    @Autowired
    private CityMapper cityMapper;

    @Override
    public void getCityList(Integer skuId) {
        /**
         * 以下三个变量在每个请求线程内共享：
         * 1、totalCityNum ：总任务数、cityId 上限，同时作为爬虫线程共享信号量
         * 2、errorNum：403 forbidden 请求数
         * 3、newCityNum：新爬取到的城市数
         */
        AtomicInteger totalCityNum = new AtomicInteger(5000);
        AtomicInteger errorNum = new AtomicInteger(0);
        AtomicInteger newCityNum = new AtomicInteger(0);

        int totalThread = 2;
        int taskNum = totalCityNum.get() / totalThread;

        CityExample cityExample = new CityExample();
        cityExample.createCriteria().andIdIsNotNull();
        Set<Integer> cityIdExist = cityMapper.selectByExample(cityExample).stream().map(o -> o.getCityid()).collect(Collectors.toSet());

        ExecutorService executorService = Executors.newFixedThreadPool(10);
        long startTime = System.currentTimeMillis();
        for (int i = 1; i <= totalThread; i++) {
            executorService.execute(new CityTask(scratchService,i,taskNum,skuId,cityIdExist,totalCityNum,errorNum));
        }
        executorService.shutdown();

        //等待爬虫线程全部执行完
        while (totalCityNum.get() > 0) {}

        //记录一下统计数据
        System.out.println("\n总共花费 " + ((System.currentTimeMillis() - startTime) / 1000) + " 秒");
        System.out.println("被禁 " + errorNum + " 条");

        for (Map.Entry<Integer, String> entry : DZDPScratchImpl.cityMap.entrySet()) {
            Integer key = entry.getKey();
            if (!cityIdExist.contains(key)) {
                String value = entry.getValue();
                City city = new City();
                city.setCityid(key);
                city.setCityname(value);
                try {
                    cityMapper.insertSelective(city);
                    newCityNum.getAndIncrement();
                } catch (Exception e) {
                    System.out.println(e.getMessage());
                    System.out.println(city.getCityid());
                }
            }
            DZDPScratchImpl.cityMap.remove(key);
        }
        System.out.println("新增 " + newCityNum + " 个城市");
        System.out.println("cityMap 是否清空：" + DZDPScratchImpl.cityMap.isEmpty());
    }
}
